#include "<SampleEd$Dir>.h.Driver"
#include <stdio.h>
#include <stdlib.h>
#include "osfile.h"
#include "kernel.h"
#include "sndfile.h"
#include "wimp.h"

/* Export MP3 file */

osbool driver_export(char *filename,int export_index,int filetype,int samplerate,int channels,int start,int size)
    {
    int channelindex,     /* Channel counter       */
        data[32],         /* Output data           */
        error,            /* Error number          */
        index,            /* Index into sample     */
        lastpc = 0,       /* Previous percentge    */
        pc,               /* Calculated percentage */
        left,
        right,
        real_channels;

    int old_next_slotsize,
        new_next_slotsize;

    char *lame_size,
         *lame_encode;

    char tmpname[L_tmpnam];

    char lame_command[1024];

    _kernel_swi_regs r;

    SF_INFO wfinfo;       /* File format info      */

    SNDFILE *sndfile;     /* libsndfile handle     */

    FILE *fh;

    NOT_USED(export_index);

/* Check that LAME can be found */

    if ((fh = fopen("Run:LAME","r")) == NULL)
        {
        driver_report_error("DrvErrLAME");
        return TRUE;
        }

    if (channels > 2)
        {
        channels = 2;
        }

    tmpnam(tmpname);

    if ((fh = fopen(tmpname,"w")) == NULL)
        {
        driver_report_error("DrvErrOpenW");
        return TRUE;
        }

    fclose(fh);

/* Get real channels */

    driver_get_sample_details(NULL,NULL,&real_channels,NULL);

/* Open file */

    wfinfo.samplerate = samplerate;
    wfinfo.channels   = channels;

    wfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;

    sndfile = sf_open(tmpname,SFM_WRITE,&wfinfo);

/* Report an error */

    error = sf_error(sndfile);

    if (error)
        {
        driver_report_error((char *)sf_error_number(error));
        }

/* Read data */

    if (sndfile != NULL)
        {
/* Loop round data */

        for (index = start;
             index < size;
             index++)
            {
/* Calculate percentage */

            pc = 100 * (index - start) / (size - start);

/* Only set percentage if different */

            if (pc > lastpc)
                {
                driver_percentage(pc);
                lastpc = pc;
                }

/* Loop round each channel */

            if (channels == real_channels)
                {
                for (channelindex = 0;
                     channelindex < channels;
                     channelindex++)
                    {
                    data[channelindex] = driver_get_sample(index,channelindex) << 16;
                    }
                }
            else
                {
                driver_mix(index,channels,&left,&right);

                if (channels == 1)
                    {
                    data[0] = left << 16;
                    }
                else
                    {
                    data[0] = left << 16;
                    data[1] = right << 16;
                    }
                }

/* Write input */

            sf_write_int(sndfile,data,channels);

/* Check for error */

            error = sf_error(sndfile);

            if (error)
                {
                driver_report_error((char *)sf_error_number(error));
                break;
                }
            }

        sf_close(sndfile);
        }

/* Run LAME command to encode file to MP3 */

    new_next_slotsize = 2048 * 1024;

    lame_size = getenv("SampleEd$LAMESlotSize");

    if (lame_size != NULL && atoi(lame_size) > new_next_slotsize)
        {
        new_next_slotsize = atoi(lame_size);
        }

/* Get old next slot size */

    r.r[0] = -1;
    r.r[1] = -1;

    _kernel_swi(Wimp_SlotSize,&r,&r);

    old_next_slotsize = r.r[1];

/* Set our next slot size */

    r.r[1] = new_next_slotsize;

    _kernel_swi(Wimp_SlotSize,&r,&r);

    if (r.r[1] < new_next_slotsize)
        {
        driver_report_error("DrvTaskMem");
        r.r[1] = old_next_slotsize;
        _kernel_swi(Wimp_SlotSize,&r,&r);
        return TRUE;
        }

    lame_encode = getenv("SampleEd$LAMEEncode");

    if (lame_encode == NULL)
        {
        lame_encode = "";
        }

    sprintf(lame_command,"lame -h --silent %s %s \"%s\" { > null: }",lame_encode,tmpname,filename);

    if (wimp_start_task(lame_command))
        {
        driver_report_error("DrvTask");
        r.r[1] = old_next_slotsize;
        _kernel_swi(Wimp_SlotSize,&r,&r);
        return TRUE;
        }

/* Reset slot size */

    r.r[1] = old_next_slotsize;
    _kernel_swi(Wimp_SlotSize,&r,&r);

    remove(tmpname);

    r.r[0] = OSFile_SetType;
    r.r[1] = (int)filename;
    r.r[2] = (int)filetype;

    _kernel_swi(XOS_File,&r,&r);

    return TRUE;
    }
